package com.example.user.service;

import cn.hutool.core.bean.BeanUtil;
import com.example.common.exception.CommonBusinessException;
import com.example.common.exception.UserNotExistsException;
import com.example.common.response.PageResponse;
import com.example.common.util.AdminUtil;
import com.example.common.util.SnowflakeUtil;
import com.example.user.entity.User;
import com.example.user.entity.UserExample;
import com.example.common.exception.UserAlreadyExistsException;
import com.example.user.mapper.UserMapper;
import com.example.user.request.LoginRequest;
import com.example.user.request.SendCodeRequest;
import com.example.user.request.UserListRequest;
import com.example.user.request.UserRequest;
import com.example.user.response.LoginResponse;
import com.example.user.response.UserResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {
    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    @Autowired
    UserMapper userMapper;

    @Autowired
    AdminUtil adminUtil;

    public long count() {
        return userMapper.countByExample(null);
    }

    public long register(UserRequest request) {
        String mobile = request.getMobile();
        List<User> users = selectByMobile(mobile);
        if (!users.isEmpty()) {
            throw new UserAlreadyExistsException();
        }

        User user = new User();
        user.setId(SnowflakeUtil.getId());
        user.setMobile(mobile);
        return userMapper.insert(user);
    }

    public void sendCode(SendCodeRequest request) {
        String mobile = request.getMobile();

        List<User> users = selectByMobile(mobile);

        if (users.isEmpty()) {
            // 如果这个手机号没注册过，就插入记录；当成他是来注册的
            User user = new User();
            user.setId(SnowflakeUtil.getId());
            user.setMobile(mobile);
            userMapper.insert(user);
            log.info("未注册过的手机号：{}，自动插入", mobile);
        }

        // 生成验证码
        //String code = RandomUtil.randomString(4);
        String code = "6666";
        log.info("生成验证码：{}，手机号：{}，业务场景：登录", code, mobile);

        // td-1：保存到验证码历史记录表
        // 建议的表字段 (id, code, mobile, 有效期, 已使用?, 业务类型[登录/忘记密码...], 生成时间, 使用时间)
        // 暂时通过打印日志模拟
        log.info("【模拟】已经保存到验证码历史记录表。验证码：{}，手机号：{}", code, mobile);

        // td-2：对接真实的短信发送服务
        log.info("【模拟】短信发送成功。验证码：{}，手机号：{}", code, mobile);
    }

    /*
    暂时先直接返回 User，实际中不应该把用户所有的信息全部返回出去，因为：
    1. 会涉及隐私的问题，比如密码字段
    2. 会涉及到很多不必要的字段，比如数据库中的创建时间、更新时间、额外标记字段等等
    3. 还会涉及到有些字段并不是 User 这个实体的字段，比如 token 等

    上面描述问题的解决方法类似之前引入的 DTO，除了 DTO 可能还会遇到 VO、BO、PO、DO、Entity、POJO 等各种词汇
    参考：https://www.cnblogs.com/east7/p/15057400.html
    这篇文章说的也不是标准答案，国内外描述也不一定一致

    为了避免记忆一大堆名词，除了 Entity，我们只用两个额外的概念去封装系统的需求：
    1. request 封装从「前端」发送到「后端」的数据
    2. response 封装从「后端」返回给「前端」的数据
     */
    public LoginResponse login(LoginRequest request, boolean isAdminLogin) {
        String mobile = request.getMobile();
        String code = request.getCode();

        // 校验验证码是否正确
        if (!"6666".equals(code)) {
            throw new CommonBusinessException("验证码错误");
        }

        List<User> users = selectByMobile(mobile);

        // 校验用户是否存在
        if (users.isEmpty()) {
            throw new UserNotExistsException();
        }

        User user = users.get(0);

        // 作为小组功能扩展点，可扩展成角色权限判断等
        if (isAdminLogin && !adminUtil.isAdmin(user.getId())) {
            throw new CommonBusinessException("权限不足");
        }

        return BeanUtil.copyProperties(user, LoginResponse.class);
    }

    private List<User> selectByMobile(String mobile) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andMobileEqualTo(mobile);
        return userMapper.selectByExample(userExample);
    }

    public PageResponse<UserResponse> list(UserListRequest request) {
        UserExample userExample = new UserExample();
        userExample.setOrderByClause("id desc");
        PageHelper.startPage(request.getPage(), request.getSize());
        log.info("当前页码 current_page = {}", request.getPage());
        log.info("每页记录数 per_page = {}", request.getSize());

        List<User> users = userMapper.selectByExample(userExample);

        PageInfo<User> pageInfo = new PageInfo<>(users);
        log.info("总记录数 total = {}", pageInfo.getTotal());
        log.info("总页数 pages = {}", pageInfo.getPages());

        List<UserResponse> userResponses = BeanUtil.copyToList(users, UserResponse.class);

        PageResponse<UserResponse> pageResponse = new PageResponse<>();
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setList(userResponses);

        return pageResponse;
    }
}
